package com.sheledon.flyCat.core.ioc;


import com.sheledon.flyCat.annotation.ioc.Autowired;
import com.sheledon.flyCat.annotation.ioc.Qualifier;
import com.sheledon.flyCat.annotation.ioc.Value;
import com.sheledon.flyCat.common.utils.BeanHelper;
import com.sheledon.flyCat.common.utils.ObjectUtils;
import com.sheledon.flyCat.common.utils.ReflectionUtils;
import com.sheledon.flyCat.core.aop.factory.AopProxyProcessorFactory;
import com.sheledon.flyCat.core.aop.intercept.BeanProcessor;
import com.sheledon.flyCat.core.configuration.ConfigurationManager;
import com.sheledon.flyCat.core.exception.InitializeObjectException;

import java.lang.reflect.Field;

/**
 * 初始化 IOC 容器内的bean
 * 包括 属性注入等
 * @author sheledon
 */
public class InitializeBeanFactory {

    public static void initializeBean(Object bean){
        Class<?> aClass = bean.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if (field.isAnnotationPresent(Autowired.class)){
                String beanName = getBeanName(field);
                Object beanInstance= BeanFactory.getBean(beanName);
                Object proxyInstance = BeanFactory.getProxyBean(beanName);
                if (proxyInstance!=null){
                    beanInstance = proxyInstance;
                }
                if (beanInstance==null){
                    throw new InitializeObjectException("Autowired can not find bean : "+ beanName);
                }
                ReflectionUtils.setFiledValue(field,bean,beanInstance);
            }
            if (field.isAnnotationPresent(Value.class)){
                Value annotation = field.getAnnotation(Value.class);
                String value = ConfigurationManager.getString(annotation.value());
                ReflectionUtils.setFiledValue(field,bean, ObjectUtils.convert(field.getType(),value));
            }
        }
    }
    private static String getBeanName(Field field){
        String beanName = field.getType().getSimpleName();
        if (field.isAnnotationPresent(Qualifier.class)){
            Qualifier annotation = field.getAnnotation(Qualifier.class);
            beanName = "".equals(annotation.name()) ? beanName : annotation.name();
        }
        return beanName;
    }

}
